#ifndef SUDOKUCELL_H_
#define SUDOKUCELL_H_

#include <QBitArray>
#include <QDebug>

#include <QMetaType>

/**
  * Possible types of inserted cell value
  */
enum CellFillerTypes
{
    /**
      * Empty cell
      */
    Empty = 1 << 0,
    /**
      * Cell filled by user.
      * Solving algorithms treat user filled cells as certain.
      */
    User = 1 << 2,
    /**
      * Cell value was known from the beginning
      */
    Certain = 1 << 3,
    /**
      * Not sure if value is correct
      */
    Guess = 1 << 4,
    /**
      * Inserted by findNakedSingles()
      * Other names: Forced Digit, Sole Candidate
      */
    NakedSingles = 1 << 5,
    /**
      * Inserted by findHiddenSingles() from rows
      */
    HiddenSinglesRow = 1 << 6,
    /**
      * Inserted by findHiddenSingles() from cols
      */
    HiddenSinglesCol = 1 << 7,
    /**
      * Inserted by findHiddenSingles() from boxes
      */
    HiddenSinglesBox = 1 << 8,
    /**
      * Inserted by findHiddenSingles() from rows, cols and boxes
      * Other names: Pinned Digit.
      */
    HiddenSingles = HiddenSinglesRow | HiddenSinglesCol | HiddenSinglesBox,
    /**
      * Inserted by findLockedCandidates1AndExclude()
      * Other names: Intersection Removal, Line-Box Interaction
      */
    LockedCandidates1 = 1 << 9,//TODO Pointing
    /**
      * Inserted by findLockedCandidates2AndExclude()
      */
    LockedCandidates2 = 1 << 10,//TODO Claiming
    /**
      * Inserted by findGroupsAndExclude()
      */
    Groups = 1 << 11,
    /**
      * Inserted by xWing()
      */
    Xwing = 1 << 12
};

/**
  * Class that represents single sudoku cell
  * @author Łukasz Szybka
  */
class SudokuCell
{
public:

    //TODO should not be used, just for qvariant
    SudokuCell();
    /**
      * Creates empty cell with all numbers possible
      */
    SudokuCell(int maxValue);
    SudokuCell(int maxValue, int _value, int _prior);
    SudokuCell(const SudokuCell& cell);
    ~SudokuCell();

    SudokuCell& operator=(const SudokuCell& cell);

    void setValue(int _value, int _prior);
    int getValue() const;
    int getPrior() const;
    void setPossibl(int index, bool possibl);
    bool getPossibl(int index) const;
    int countPossible() const;
    int getPossiblArrSize();

    bool isEmpty() const;

    void clear();

    friend QDebug operator<<(QDebug dbg, const SudokuCell& cell);

    static bool hasMoreClues(const SudokuCell* cell1, const SudokuCell* cell2);
    static bool hasLessClues(const SudokuCell* cell1, const SudokuCell* cell2);

protected:
    /**
      * 0 means that cell is empty
      */
    int value;
    /**
      *
      */
    int prior;
    /**
      * array with possible numbers to insert
      */
    QBitArray possiblArr;


private:
};

 Q_DECLARE_METATYPE(SudokuCell)

#endif /*SUDOKUCELL_H_*/
